From 9a1cd8393302086c92af5684c24f6cb4bbb94e85 Mon Sep 17 00:00:00 2001 From: Cosimo Cecchi Date: Thu, 18 Nov 2010 18:44:28 +0100 Subject: [PATCH] open-with-widget: add support for fallback applications Needs some new API in GIO, which is not yet merged. --- gtk/gtkopenwithwidget.c | 204 +++++++++++++++++++++++----------------- 1 file changed, 117 insertions(+), 87 deletions(-) diff --git a/gtk/gtkopenwithwidget.c b/gtk/gtkopenwithwidget.c index 407dc7910c..c309def802 100644 --- a/gtk/gtkopenwithwidget.c +++ b/gtk/gtkopenwithwidget.c @@ -62,6 +62,7 @@ enum { COLUMN_HEADING, COLUMN_HEADING_TEXT, COLUMN_RECOMMENDED, + COLUMN_FALLBACK, NUM_COLUMNS }; @@ -346,6 +347,7 @@ gtk_open_with_sort_func (GtkTreeModel *model, gpointer user_data) { gboolean a_recommended, b_recommended; + gboolean a_fallback, b_fallback; gboolean a_heading, b_heading; gchar *a_name, *b_name, *a_casefold, *b_casefold; gint retval; @@ -359,12 +361,14 @@ gtk_open_with_sort_func (GtkTreeModel *model, gtk_tree_model_get (model, a, COLUMN_NAME, &a_name, COLUMN_RECOMMENDED, &a_recommended, + COLUMN_FALLBACK, &a_fallback, COLUMN_HEADING, &a_heading, -1); gtk_tree_model_get (model, b, COLUMN_NAME, &b_name, COLUMN_RECOMMENDED, &b_recommended, + COLUMN_FALLBACK, &b_fallback, COLUMN_HEADING, &b_heading, -1); @@ -381,7 +385,20 @@ gtk_open_with_sort_func (GtkTreeModel *model, goto out; } - /* they're both recommended or not, so if one is a heading, wins */ + /* the recommended one always wins */ + if (a_fallback && !b_fallback) + { + retval = -1; + goto out; + } + + if (b_fallback && !a_fallback) + { + retval = 1; + goto out; + } + + /* they're both recommended/falback or not, so if one is a heading, wins */ if (a_heading) { return -1; @@ -463,57 +480,45 @@ compare_apps_func (gconstpointer a, } static void -gtk_open_with_widget_real_add_items (GtkOpenWithWidget *self) +gtk_open_with_widget_add_section (GtkOpenWithWidget *self, + const gchar *heading_title, + gboolean show_headings, + gboolean recommended, + gboolean fallback, + GList *applications, + GList *exclude_apps) { - GList *all_applications = NULL, *content_type_apps = NULL, *l; - gchar *app_string; - GIcon *icon; gboolean heading_added, unref_icon; - gboolean show_recommended, show_headings, show_all; - - if (self->priv->show_mode == GTK_OPEN_WITH_WIDGET_SHOW_MODE_RECOMMENDED) - { - show_all = FALSE; - show_headings = FALSE; - show_recommended = TRUE; - } - else if (self->priv->show_mode == GTK_OPEN_WITH_WIDGET_SHOW_MODE_ALL) - { - show_all = TRUE; - show_headings = FALSE; - show_recommended = FALSE; - } - else - { - show_all = self->priv->show_more_clicked; - show_headings = TRUE; - show_recommended = TRUE; - } - - if (show_recommended) - content_type_apps = g_app_info_get_all_for_type (self->priv->content_type); - - if (show_all) - all_applications = g_app_info_get_all (); + GtkTreeIter iter; + GAppInfo *app; + gchar *app_string, *bold_string; + GIcon *icon; + GList *l; heading_added = FALSE; + bold_string = g_strdup_printf ("%s", heading_title); - for (l = content_type_apps; l != NULL; l = l->next) + for (l = applications; l != NULL; l = l->next) { - GAppInfo *app = l->data; - GtkTreeIter iter; + app = l->data; if (!g_app_info_supports_uris (app) && !g_app_info_supports_files (app)) continue; + if (exclude_apps != NULL && + g_list_find_custom (exclude_apps, app, + (GCompareFunc) compare_apps_func)) + continue; + if (!heading_added && show_headings) { gtk_list_store_append (self->priv->program_list_store, &iter); gtk_list_store_set (self->priv->program_list_store, &iter, - COLUMN_HEADING_TEXT, _("Recommended Applications"), + COLUMN_HEADING_TEXT, bold_string, COLUMN_HEADING, TRUE, - COLUMN_RECOMMENDED, TRUE, + COLUMN_RECOMMENDED, recommended, + COLUMN_FALLBACK, fallback, -1); heading_added = TRUE; @@ -540,7 +545,8 @@ gtk_open_with_widget_real_add_items (GtkOpenWithWidget *self) COLUMN_DESC, app_string, COLUMN_EXEC, g_app_info_get_executable (app), COLUMN_HEADING, FALSE, - COLUMN_RECOMMENDED, TRUE, + COLUMN_RECOMMENDED, recommended, + COLUMN_FALLBACK, fallback, -1); g_free (app_string); @@ -550,65 +556,88 @@ gtk_open_with_widget_real_add_items (GtkOpenWithWidget *self) unref_icon = FALSE; } - heading_added = FALSE; + g_free (bold_string); +} - for (l = all_applications; l != NULL && show_all; l = l->next) - { - GAppInfo *app = l->data; - GtkTreeIter iter; +static void +add_no_applications_label (GtkOpenWithWidget *self) +{ + gchar *string, *string2, *desc; + GtkTreeIter iter; - if (!g_app_info_supports_uris (app) && - !g_app_info_supports_files (app)) - continue; + desc = g_content_type_get_description (self->priv->content_type); + string2 = g_strdup_printf (_("Cannot find any compatible application for \"%s\""), + desc); - if (content_type_apps != NULL && - g_list_find_custom (content_type_apps, app, - (GCompareFunc) compare_apps_func)) - continue; + string = g_strdup_printf ("%s\n%s", + string2, + _("Click on \"Show more applications\" for a list of fallback options")); - if (!heading_added && show_headings) - { - gtk_list_store_append (self->priv->program_list_store, &iter); - gtk_list_store_set (self->priv->program_list_store, &iter, - COLUMN_HEADING_TEXT, _("Other Applications"), - COLUMN_HEADING, TRUE, - COLUMN_RECOMMENDED, FALSE, - -1); + gtk_list_store_append (self->priv->program_list_store, &iter); + gtk_list_store_set (self->priv->program_list_store, &iter, + COLUMN_HEADING_TEXT, string, + COLUMN_HEADING, TRUE, + COLUMN_RECOMMENDED, TRUE, + -1); - heading_added = TRUE; - } + g_free (string); + g_free (string2); + g_free (desc); +} - app_string = g_strdup_printf ("%s\n%s", - g_app_info_get_display_name (app) != NULL ? - g_app_info_get_display_name (app) : "", - g_app_info_get_description (app) != NULL ? - g_app_info_get_description (app) : ""); +static void +gtk_open_with_widget_real_add_items (GtkOpenWithWidget *self) +{ + GList *all_applications = NULL, *content_type_apps = NULL, *recommended_apps = NULL, *fallback_apps = NULL; + gboolean show_recommended, show_headings, show_all; - icon = g_app_info_get_icon (app); - if (icon == NULL) - { - icon = g_themed_icon_new ("application-x-executable"); - unref_icon = TRUE; - } + if (self->priv->show_mode == GTK_OPEN_WITH_WIDGET_SHOW_MODE_RECOMMENDED) + { + show_all = FALSE; + show_headings = FALSE; + show_recommended = TRUE; + } + else if (self->priv->show_mode == GTK_OPEN_WITH_WIDGET_SHOW_MODE_ALL) + { + show_all = TRUE; + show_headings = FALSE; + show_recommended = FALSE; + } + else + { + show_all = self->priv->show_more_clicked; + show_headings = TRUE; + show_recommended = TRUE; + } - gtk_list_store_append (self->priv->program_list_store, &iter); - gtk_list_store_set (self->priv->program_list_store, &iter, - COLUMN_APP_INFO, app, - COLUMN_GICON, icon, - COLUMN_NAME, g_app_info_get_display_name (app), - COLUMN_DESC, app_string, - COLUMN_EXEC, g_app_info_get_executable (app), - COLUMN_HEADING, FALSE, - COLUMN_RECOMMENDED, FALSE, - -1); + if (show_recommended) + { + recommended_apps = g_app_info_get_recommended_for_type (self->priv->content_type); + fallback_apps = g_app_info_get_fallback_for_type (self->priv->content_type); + content_type_apps = g_list_concat (g_list_copy (recommended_apps), + g_list_copy (fallback_apps)); + } - g_free (app_string); - if (unref_icon) - g_object_unref (icon); + if (show_all) + all_applications = g_app_info_get_all (); - unref_icon = FALSE; + if (show_recommended) + { + if (recommended_apps != NULL) + gtk_open_with_widget_add_section (self, _("Recommended Applications"), + show_headings, TRUE, FALSE, recommended_apps, NULL); + else if (!self->priv->show_more_clicked) + add_no_applications_label (self); } + if (show_all) + gtk_open_with_widget_add_section (self, _("Fallback Applications"), + show_headings, FALSE, TRUE, fallback_apps, recommended_apps); + + if (show_all) + gtk_open_with_widget_add_section (self, _("Other Applications"), + show_headings, FALSE, FALSE, all_applications, content_type_apps); + if (content_type_apps != NULL) g_list_free_full (content_type_apps, g_object_unref); @@ -632,6 +661,7 @@ gtk_open_with_widget_add_items (GtkOpenWithWidget *self) G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_STRING, + G_TYPE_BOOLEAN, G_TYPE_BOOLEAN); sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (self->priv->program_list_store)); @@ -665,14 +695,14 @@ gtk_open_with_widget_add_items (GtkOpenWithWidget *self) renderer = gtk_cell_renderer_text_new (); gtk_tree_view_column_pack_start (column, renderer, FALSE); gtk_tree_view_column_set_attributes (column, renderer, - "text", COLUMN_HEADING_TEXT, + "markup", COLUMN_HEADING_TEXT, "visible", COLUMN_HEADING, NULL); g_object_set (renderer, - "weight", PANGO_WEIGHT_BOLD, - "weight-set", TRUE, "ypad", 6, "xpad", 0, + "wrap-width", 350, + "wrap-mode", PANGO_WRAP_WORD, NULL); /* padding renderer for non-heading cells */ -- 2.30.2